#ifndef VSqlMeta_H
#define VSqlMeta_H

#include "VSqlItem.h"
#include "VSqlNode.h"

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

class VSqlMetaColumn
{
public:
	enum EType { EType_unknown,EType_node,EType_item };

public:
	VSqlMetaColumn() :m_type(EType_unknown),m_colField(-1) {}

	void setType(EType v) { m_type = v;}
	EType type() const { return m_type;}
	bool isNode() const { return m_type == EType_node;}

	void setField(const QSqlField &v,int colField) { m_field = v; m_colField = colField;}
	QSqlField field() const { return m_field;}
	int colField() const { return m_colField;}

	QString displayName() const;

private:
	EType m_type;
	QSqlField m_field;
	int m_colField;
};

///////////////////////////////////////////////////////////////////////////////

class VSqlMetaColumnList : public QList<VSqlMetaColumn>
{
public:
	VSqlMetaColumnList();

	int indexOf(VSqlMetaColumn::EType type,const QString &fieldName) const;

	int colNode_idNode() const { return m_colNode_idNode;}
	int colNode_refIdItem() const { return m_colNode_refIdItem;}
	int colNode_refIdRec() const { return m_colNode_refIdRec;}

	int colKeyNameUpper() const { return m_colKeyNameUpper;}
	int colDisplayName() const { return m_colDisplayName;}
	int colItemType()	const { return m_colItemType;}
	int colItem_refIdItem() const { return m_colItem_refIdItem;}

private:
	int m_colNode_idNode;
	int m_colNode_refIdItem;
	int m_colNode_refIdRec;

	int m_colKeyNameUpper;
	int m_colDisplayName;
	int m_colItemType;
	int m_colItem_refIdItem;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

class VSqlMetaRecord
{
	V_COUNTER_OBJECTS(VSqlMetaRecord)
	
public:
	VSqlMetaRecord() :m_hasChildren(false),m_parent(NULL),m_isFetch(false) {}
	~VSqlMetaRecord() { clear();}
	
	void clear();

	VSqlMetaRecord *parent() { return m_parent;}

	void setNode(const VSqlSharedRecordPtr &v) { m_node = v;}
	VSqlSharedRecordPtr node() const { return m_node;}
	
	void setItem(const VSqlSharedRecordPtr &v) { m_item = v;}
	VSqlSharedRecordPtr item() const { return m_item;}
	
	void setRecord(const VSqlMetaRecord *v);

	void setHasChildren(bool v) { m_hasChildren = v;}
	bool hasChildren() const { return m_hasChildren;}
	bool hasChildren(const QSqlDatabase &db);

	void clearChildren();
	void setChildren(const QList<VSqlMetaRecord*> &v);
	QList<VSqlMetaRecord*> children() const { return m_children;}

	//void appendChild(VSqlMetaRecord *child);
	void insertChild(int row,VSqlMetaRecord *child);
	int childCount() const { return m_children.count();}
	VSqlMetaRecord *child(int row) const { return m_children[row];}
	int row() const;

	QVariant data(int column,const VSqlMetaColumnList &columnList) const;
	void  setData(int column,const VSqlMetaColumnList &columnList,const QVariant &value);

	void setIsFetch(bool v) { m_isFetch = v;}
	bool isFetch() const { return m_isFetch;}

private:
	VSqlSharedRecordPtr m_node;
	VSqlSharedRecordPtr m_item;

	VSqlMetaRecord *m_parent;
	QList<VSqlMetaRecord*> m_children;
	bool m_hasChildren;
	bool m_isFetch;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

class VSqlMeta
{
public:
	VSqlMeta() {}
	VSqlMeta(VSqlMetaRecord *r) { setValues(r);}
	
	bool isNull() const { return m_node.isNull() || m_item.isNull();}

	void setNode(const VSqlNode &v) { m_node = v;}
	VSqlNode *nodePtr() { return &m_node;}
	VSqlNode node() const { return m_node;}

	void setItem(const VSqlItem &v) { m_item = v;}
	VSqlItem *itemPtr() { return &m_item;}
	VSqlItem item() const { return m_item;}

	void setValues(const VSqlMetaRecord *r);
	void setRecord(VSqlMetaRecord *r) const;

private:
	VSqlNode m_node;
	VSqlItem m_item;
};

///////////////////////////////////////////////////////////////////////////////

#endif
